<template>
  <!-- Popover 鼠标移入展示 -->
  <div
    ref="ReferenceOFFSET"
    @mouseenter="onMouseenter"
    @mouseleave="onMouseLeave"
    class="relative"
  >
    <!-- 根据插槽动态显示需要的内容 -->
    <slot name="reference"></slot>
    <transition name="fade" duration="200">
      <div
        ref="popover"
        v-show="isVisible"
        class="absolute p-1 z-20 dark:text-zinc-100 dark:bg-zinc-800 rounded-sm"
        :style="contentStyle"
      >
        <!-- 弹出层中具体内容 -->
        <slot></slot>
      </div>
    </transition>
  </div>
</template>
<script setup>
import { nextTick, ref, defineProps, watch } from 'vue'
const props = defineProps({
  placement: {
    type: String,
    default: 'LT' // 默认左上角
  }
})
const isVisible = ref(false)
const ReferenceOFFSET = ref(null)
const popover = ref(null)
const contentStyle = ref({ left: '', top: '' })
const calculatePopoverPosition = () => {
  const referenceRect = ReferenceOFFSET.value.getBoundingClientRect()
  const popoverRect = popover.value.getBoundingClientRect()
  // 根据不同的 `placement` 确定 `contentStyle`
  switch (props.placement) {
    case 'LT': // 左上
      contentStyle.value = {
        left: `${-popoverRect.width}px`,
        top: `${-popoverRect.height + referenceRect.height}px`
      }
      break
    case 'LB': // 左下
      contentStyle.value = {
        left: `${-popoverRect.width}px`,
        top: `${referenceRect.height + 12}px`
      }
      break
    case 'RT': // 右上
      contentStyle.value = {
        left: `${referenceRect.width}px`,
        top: `${-popoverRect.height + referenceRect.height}px`
      }
      break
    case 'RB': // 右下
      contentStyle.value = {
        left: `${referenceRect.width}px`,
        top: `${referenceRect.height}px`
      }
      break
  }
}

// 监控 `isVisible` 变化，更新位置
watch(isVisible, (newValue) => {
  if (!isVisible.value) return
  nextTick(calculatePopoverPosition)
})

// 显示和隐藏 Popover
const onMouseenter = () => {
  isVisible.value = true
}
const onMouseLeave = () => {
  isVisible.value = false
}
</script>

<style lang="scss" scoped>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.2s;
}
.fade-enter,
.fade-leave-to {
  opacity: 0;
}
</style>
